模拟赛题解/2025.9.2 模拟赛
T1-删树游戏(game)
题面
有一棵由编号为 的 个节点构成的有根树,其中 为根节点, 号点的父亲为 。此外,每个节点都有一个互不相同的整数权值, 号节点的权值为 。保证 为 的一个排列。
我们从 出发,每次移动到当前节点的子节点中权值最小的一个。如此重复,直到到达某个叶子节点。这样得到的路径记作 ,我们称其为特殊路径。
定义一次删除操作如下:
- 设当前树的特殊路径为 。
- 令 从 到 ,依次执行:交换 与 。
- 删除树中 与其父亲相连的边。
我们对这棵树进行 次删除操作,你需要在每次操作前求出 号点的权值 。
。
题解
定义删除序列 , 为这一棵树第 操作前根节点的权值。
对于一个点 ,设它操作选中了子节点 多次,那么 的变化一定形如 子树的删除序列。
那么求 子树的操作序列相当于先加入 ,然后把子节点的删除序列归并起来。
注意到这个删除序列就是 子树的一个 BFS 序,而且我们要最小化这个 BFS 序的权值的字典序。
用堆维护 BFS 即可。每次取出最小权值点后加入所有的子节点。
复杂度 。
T2-身份猜测(identity)
题面
这是一道交互题。
现有 个人,编号为 。其中恰有 个人是诚实的, 个人是不诚实的。每个人都清楚所有人的身份,但你知道的仅有 和 的值。你需要去确定每个人的身份。
如果你在已知 的情况下无法通过询问确定所有人的身份,则报告不可能。
否则,你可以进行不超过 次询问。每次给定 和 ,向 询问 的身份,交互库返回规则如下:
- 如果 是诚实的,那么 会如实返回 的身份。
- 如果 是不诚实的, 会任意选择回答。注意 可以按照某种策略回答。
交互库会通过你的询问次数评分。
- 如果你未能正确判断有无解,或交互过程不合法,得 分。
- 如果无解,得 分。
- 否则,如果你返回的身份不正确,得 分。
- 否则,你的得分由查询次数 决定:
q | 得分 |
---|---|
40 | |
55 | |
65 | |
85 | |
100 |
且 。
题解
一个观察是,我们能分辨身份当且仅当 。
如果 ,那么我们可以从 个假的人中选出 个人,对这 个人询问时按照这 个人为真,其他都为假来回答。然后就无法判断这 个人是真是假。
如果 ,那么对于每个人 ,我们询问其他所有人对他的评价。如果有 个人认为他是真的,那 么就是真的,否则即为假。注意到我们可以认为 声称 是真的,那么只要做 次。
考虑去找一个真的人,然后再通过他问出所有人的身份。
因为 ,考虑类似摩尔投票的思路。
如果 认为 是假的,那么 和 中有至少一个为假,可以直接删除。
否则,如果 和 都认为对面是真的,那么 和 的种类相同。
于是有一个 次的做法:
- 我们维护集合 ,满足 中的人的种类相同。加入一个人 时,讨论和集合中任意一个人 的关系。
- 如果 认为 假或 认为 假,那么可以直接删除 和 。
- 如果 和 都认为对面是真的,那么就把 加入 。
考虑优化。我们不需要维护一个身份相同的集合,而是维护一条链 ,满足 认为 是真的。
实际上, 的真实身份一定是一段前缀是假的,剩下一段后缀是真的。
那么每次我们加入 时,只要看 是否认为 是真的。如果是,则加入 ,否则删除 和 。
因为 ,而我们每次删除的 和 中至少有一个是假的,因此最终的 一定包含真人,即 一 定为真。
那么我们再拿 把所有人问一遍即可。询问次数 。
T3-序列计数(count)
题面
给定一个长度为 的自然数序列 ,满足 。
序列还需满足 条限制。
第 条限制为 。
请输出合法的序列 的个数,对 取模。
题解
对于第 个限制,它首先约束了 都是不超过 的。
记 为 的上界。这个可以直接并查集预处理。
考虑对值域扫描。
对于一个 ,我们在处理 的限制时, 的点都是不用管的。因为它们不可能成为一个区间的 。因此我们可以取出所有 的点和 的限制。
那么这时限制就变成一个区间必须包含至少一个 的点。
考虑 表示 ,此时 之前的点方案数。
那么下一个 的点 需要满足不存在区间满足 ,这样的 形如一段前缀,可以差分解决。
时间复杂度 。
T4-树上查询(tree)
题面
有一棵由编号为 的 个节点构成的有根树,边有边权。 为根节点,节点 的父亲为 。对于 , 与 之间的边权为 。
定义 为 子树内经过 的最长链长度。
进行 次操作,每次将一条边的边权加上一个正整数。
在第一次操作前和每次操作后,输出
-
。
-
时 。
-
每次操作 。
题解
是 子树内以 为端点的最长链和与最长链无公共边的次长链之和。
对于每一个点 ,我们记录 为子树内与 距离最大值和次大值。这里次大值到 的链需要 和最大值的无公共边。
考虑动态维护长链剖分,那么子树的 就是实链上儿子的 ,次长链 就是虚儿子的 的最大值。
对于一次修改 ,我们先对 子树内的 和 整体加 。
然后找到 子树内最大的深度,对于 的所有祖先去更新。它对于长剖的影响是把 到根链上一段后缀 变成实链。
这个是和 LCT access 类似的,一个结论是虚实边变化次数是 的。证明考虑轻重链剖分,这 个就是在 dfs 序上颜色段均摊。
那么考虑去数据结构统一维护实边,暴力修改虚边。
一条实链,操作相当于对一条链的 加上 。
对于一条虚边,操作相当于对于单点查询 和 ,然后进行单点改。
于是我们需要支持:
- 子树加,查子树最大深度。
- 对于 子树加、链加,查单点。
- 对于 子树加,查单点。
- 动态修改一个点是否是实儿子。
- 查询一个点所在长链顶点。
第一条线段树维护,第二三条可以树状数组维护。
第四五条 std 用了倍增树状数组维护,复杂度 。常数较小,可以通过。
实际上也可以用一些办法去掉一个 ,做到 。